package org.hyh.core.security.Filter;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.hyh.core.Exception.TokenAuthenticationException;
import org.hyh.core.model.entity.SysUser;
import org.hyh.core.model.properties.JwtProperties;
import org.hyh.core.security.handler.handlerWhenLoginFail;
import org.hyh.core.service.UserService;
import org.hyh.core.utils.JwtUtils;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.Assert;
import org.springframework.web.filter.GenericFilterBean;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @auther :hyh
 * @desc :
 * @date :2020/7/12
 */
@Slf4j
@Data
public class JwtTokenValidateFilter extends GenericFilterBean {

    private RequestMatcher requiresAuthenticationRequestMatcher;
    private UserService  userService;
    private AuthenticationFailureHandler failureHandler=new handlerWhenLoginFail();

    public JwtTokenValidateFilter() {
    }

    public JwtTokenValidateFilter(RequestMatcher requiresAuthenticationRequestMatcher, UserService userService) {
        this.requiresAuthenticationRequestMatcher = requiresAuthenticationRequestMatcher;
        this.userService = userService;
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest  request =(HttpServletRequest) req;
        HttpServletResponse  response =(HttpServletResponse) resp;
        String token = request.getHeader(JwtProperties.TOKEN_HEADER_NAME);
        System.out.println(request.getContextPath());
        if (!requiresAuthenticationRequestMatcher.matches(request)) {

            if (StringUtils.isBlank(token)) {
                log.info("--->访问令牌不存在！");
                failureHandler.onAuthenticationFailure(request,response,new TokenAuthenticationException("访问令牌不存在"));
//            throw new TokenAuthenticationException("访问令牌不存在！");
                return;
            }
            //todo 为什么这里抛出的异常， 不被ExceptionTranslationFilter  拦截 执行。
            SysUser sysUser = JwtUtils.parseToken(token);
            sysUser.setPassword("123");
            sysUser.setAuthorities(AuthorityUtils.createAuthorityList("ROLE_train_user", "ROLE_train_admin"));
            UsernamePasswordAuthenticationToken authenticationToken =
                    new UsernamePasswordAuthenticationToken(sysUser, sysUser.getPassword(), sysUser.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);

        }
        filterChain.doFilter(request,response);
    }

//
//    @Override
//    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//
//        String token = request.getHeader(JwtProperties.TOKEN_HEADER_NAME);
//        System.out.println(request.getContextPath());
//        if (!requiresAuthenticationRequestMatcher.matches(request)) {
//
//            if (StringUtils.isBlank(token)) {
//                log.info("--->访问令牌不存在！");
//                failureHandler.onAuthenticationFailure(request,response,new TokenAuthenticationException("访问令牌不存在"));
////            throw new TokenAuthenticationException("访问令牌不存在！");
//                return;
//            }
//            SysUser sysUser = JwtUtils.parseToken(token);
//
//        }
//        filterChain.doFilter(request,response);
//    }

    @Override
    public void afterPropertiesSet() throws ServletException {
        Assert.notNull(requiresAuthenticationRequestMatcher, "authenticationManager must be specified");
        Assert.notNull(userService, "authenticationManager must be specified");
    }
}
